#include "TelegrafLib.h"

std::string intToString(int value) 
{
	std::ostringstream oss;
	oss << value;
	return oss.str();
}

int main() 
{
	std::string postData1 = "cpu_usage2,host=server5,region=us-east usage=15.1,idle=34.5 1617885600000000000\n"
							 "cpu_usage2,host=server6,region=us-east usage=85.1,idle=24.5 1617885600000000000";
	std::string postData2 = "cpu_usage,host=server9,region=us-east usage=85.5,idle=14.5 1617885600000000000\n"
							 "cpu_usage,host=server10,region=us-west usage=72.4,idle=27.6 1617885600000000000";
	//1、构造初始化
	DBConfig config("kwdb_jdk.ini");
	//config.print();

    #if 0
	//2、 时序测试
	//行数据写入 先login后才能insert操作
	int retLogin = config.login();//0表示成功  时序库登录
	int retAutoInsert = config.insert(postData1);//自动建表插入
	int retManInsert = config.insert(postData2,1);//手动建表插入

	//根据 Telegraf 数据及数据顺序提前在 KaiwuDB 数据库创建好对应的时序表
	//将 InfluxDB Line 格式的数据转为 SQL 语句，然后执行写入操作
	//第一列必须是时间戳列，且列名必须为 k_timestamp。
	//主标签必须命名为 primary_tag，且数据类型必须为 VARCHAR
	// 
	// 使用手动建表插入
	/* 
	-- Drop table
	-- DROP TABLE hisdb.cpu_usage ;
	CREATE TABLE cpu_usage (
	k_timestamp TIMESTAMPTZ(3) NOT NULL DEFAULT 'now()',
	usage FLOAT8 NOT NULL,
	idle FLOAT8 NOT NULL
	) TAGS (
	region VARCHAR(50) NOT NULL,
	host VARCHAR(50) NOT NULL,
	primary_tag VARCHAR(254) ) PRIMARY TAGS(host)
	retentions 0day
	activetime 1day
	partition interval 10day;
	*/ 

	/*示例
	INSERT INTO hisdb.cpu_usage
	(k_timestamp, "usage", idle, region, host, primary_tag)
		VALUES('2021-04-08 20:40:00.000', 85.5, 14.5, 'us-east', 'server3', NULL);
	*/
	#endif

	// 关系数据库接口初始化
	DBConfig::ConnectionStatus conn_status = config.connectInitDB();
	if (conn_status == DBConfig::CONNECTION_OK) 
	{
		std::cout << "DB连接成功" << std::endl;
		// 创建表测试
		std::vector<std::string> columns;
		columns.push_back("id");
		columns.push_back("name");
		columns.push_back("height");

		if (config.createTableIfNotExists("test", columns, "id")) 
		{



			#if 0
			// 第1条数据
			std::map<std::string, std::string> record1;
			record1["id"] = "1";
			record1["name"] = "test";
			record1["height"] = "1.75";
			if (config.insertToDB("test", record1)) 
			{
				//success_count++;
				std::cout << "插入第1条记录成功" << std::endl;
			} 
			else 
			{
				std::cout << "插入失败在第1条记录: " << config.getLastError() << std::endl;
				config.executeCommand("ROLLBACK");
			}
			#endif


			std::cout << "表创建成功或已存在" << std::endl;			
			#if 1
			//1、普通 insert事务批量数据
			std::vector<std::map<std::string, std::string>> batch_data;
			std::cout << "生成测试数据..." << std::endl;
			for (int i = 1; i <= 1000; i++) 
			{
				std::map<std::string, std::string> record;
				record["id"] = intToString(i);
				record["name"] = "sensor_" + intToString(i);
				double value = 20.0 + (i % 15) + (double)(i % 100) / 100.0;
				std::ostringstream value_oss;
				value_oss << std::fixed << value;
				record["height"] = value_oss.str();
				batch_data.push_back(record);
			}
			std::cout << "生成完成，共 " << batch_data.size() << " 条记录" << std::endl;
			
			time_t gen_end_time = time(NULL);
			clock_t start_clock = clock();
			struct tm* gen_end_timeinfo = localtime(&gen_end_time);
			char gen_end_time_buffer[64];
			strftime(gen_end_time_buffer, sizeof(gen_end_time_buffer), "%Y-%m-%d %H:%M:%S", gen_end_timeinfo);
			std::cout << "开始时间: " << gen_end_time_buffer << " 时间戳: " <<gen_end_time << " 时钟: " << start_clock<< std::endl;

			if (!config.executeCommand("BEGIN")) 
			{
				std::cout << "开始事务失败: " << config.getLastError() << std::endl;
				return -1;
			}
			int success_count = 0;
			const int REPORT_INTERVAL = 100; // 每100条报告一次进度
			for (size_t i = 0; i < batch_data.size(); i++) 
			{
				if (config.insertToDB("test", batch_data[i])) 
				{
					success_count++;

					/*/ 进度报告
					if ((i + 1) % REPORT_INTERVAL == 0) 
					{
						std::cout << "已插入 " << (i + 1) << "/" << batch_data.size() << " 条记录" << std::endl;
					}
					*/
				} 
				else 
				{
					std::cout << "插入失败在第 " << i << " 条记录: " << config.getLastError() << std::endl;
					config.executeCommand("ROLLBACK");
					std::cout << "事务已回滚，成功插入 " << success_count << " 条记录" << std::endl;
					return -1;
				}
			}
			if (config.executeCommand("COMMIT")) 
			{
				//std::cout << "批量插入成功! 共插入 " << success_count << " 条记录" << std::endl;
			} 
			else 
			{
				std::cout << "提交事务失败: " << config.getLastError() << std::endl;
				config.executeCommand("ROLLBACK");
			}
			time_t gen_end_time0 = time(NULL);
			clock_t end_clock = clock();
			struct tm* gen_end_timeinfo0 = localtime(&gen_end_time0);
			char gen_end_time_buffer0[64];
			strftime(gen_end_time_buffer0, sizeof(gen_end_time_buffer0), "%Y-%m-%d %H:%M:%S", gen_end_timeinfo0);
			std::cout << "结束时间: " << gen_end_time_buffer0 << " 时间戳: " <<gen_end_time0 << " 时钟: " << end_clock<< std::endl;

			double precise_duration0 = double(end_clock - start_clock) * 1000 / CLOCKS_PER_SEC;
			std::cout << "insert 精确耗时（毫秒）："<< precise_duration0 << std::endl;
			//*/
			#endif
			
			// 查询数据
			#if 0
			std::vector<std::string> cols;
			cols.push_back("id");
			cols.push_back("name");
			cols.push_back("value");
			QueryResult result = config.selectFromDB("sensor_data", cols, "", "name DESC", 10);
			// 生成：SELECT id, name, value FROM users WHERE id = 'sensor_1167328' ORDER BY name DESC LIMIT 1
			if (result.success) 
			{
				std::cout << "查询到 " << result.row_count << " 条记录:" << std::endl;
				//列名
				for (size_t i = 0; i < result.columns.size(); i++) 
				{
					std::cout << result.columns[i] << "\t";
				}
				std::cout << std::endl;
				//数据
				for (size_t i = 0; i < result.rows.size(); i++) 
				{
					std::cout << result.rows[i]["id"] << "\t"<< result.rows[i]["name"] << "\t" << result.rows[i]["value"] << std::endl;
				}
			} 
			else 
			{
				std::cout << "查询失败: " << result.error_message << std::endl;
			}
			#endif
			//getchar();
			#if 1
			// 2、 COPY批量快速插入
			// 手动创建测试数据并调用batchInsertToDB
			// 生成10000条测试数据并批量插入
			std::vector<std::map<std::string, std::string>> test_data;
			int const icount = 1000;// 生成10000条测试数据
			for (int i = 1; i <= icount; i++) 
			{
				std::map<std::string, std::string> record;
				record["id"] = intToString(i+100000);
				record["name"] = "sensor_" + intToString(i);
				double value = 20.0 + (i % 15) + (double)(i % 100) / 100.0;
				std::ostringstream value_oss;
				value_oss << std::fixed << value;
				record["height"] = value_oss.str();
				test_data.push_back(record);
				/* 每1000条显示一次进度
				if (i % 1000 == 0) {
					std::cout << "已生成 " << i << " 条数据..." << std::endl;
				}
				*/
			}
			std::cout << "数据生成完成! 共 " << test_data.size() << " 条记录" << std::endl;
			// 执行批量插入
			time_t gen_end_time1 = time(NULL);
			clock_t start_clock1 = clock();
			struct tm* gen_end_timeinfo1 = localtime(&gen_end_time1);
			char gen_end_time_buffer1[64];
			strftime(gen_end_time_buffer1, sizeof(gen_end_time_buffer1), "%Y-%m-%d %H:%M:%S", gen_end_timeinfo1);
			std::cout << "开始时间: " << gen_end_time_buffer1 << " 时间戳: " <<gen_end_time1 << " 时钟: " << start_clock1<< std::endl;

			if (config.batchInsertToDB("test", test_data)) 
			{
				std::cout << test_data.size() << "条记录 批量插入成功!" << std::endl;
				int row_count = config.getRowCount("test");
				std::cout << "表中现有 " << row_count << " 条记录" << std::endl;
			} 
			else 
			{
				std::cout << "批量插入失败: " << config.getLastError() << std::endl;
			}
			time_t gen_end_time2 = time(NULL);
			clock_t end_clock2 = clock();
			struct tm* gen_end_timeinfo2 = localtime(&gen_end_time2);
			char gen_end_time_buffer2[64];
			strftime(gen_end_time_buffer2, sizeof(gen_end_time_buffer2), "%Y-%m-%d %H:%M:%S", gen_end_timeinfo2);
			std::cout << "结束时间: " << gen_end_time_buffer2 << " 时间戳: " <<gen_end_time2 << " 时钟: " << end_clock2<< std::endl;
			
			// 计算精确耗时（毫秒）
			double precise_duration2 = double(end_clock2 - start_clock1) * 1000 / CLOCKS_PER_SEC;
			std::cout << "COPY 耗时（毫秒）："<< precise_duration2 << std::endl;
			#endif

			#if 0
			//查询示例
			QueryResult result = config.executeQuery("SELECT id, name, value FROM sensor_data WHERE id = 'sensor_1167328'");
			if (result.success) 
			{
				std::cout << "查询到 " << result.row_count << " 条记录:" << std::endl;
				//列名
				for (size_t i = 0; i < result.columns.size(); i++) 
				{
					std::cout << result.columns[i] << "\t";
				}
				std::cout << std::endl;
				//数据
				for (size_t i = 0; i < result.rows.size(); i++) 
				{
					std::cout << result.rows[i]["id"] << "\t"<< result.rows[i]["name"] << "\t" << result.rows[i]["value"] << std::endl;
				}
			} 
			else 
			{
				std::cout << "查询失败: " << result.error_message << std::endl;
			}
			#endif
		}
		else
			std::cout << "表创建失败" << std::endl;
		config.disconnectFromDB();
	}
	std::cout << "按任意键回车退出！" << std::endl;
	getchar();
	return 0;
}
